package com.wswy.wzcx.api

import android.content.Intent
import android.os.SystemClock
import android.support.annotation.WorkerThread
import android.support.v4.util.LruCache
import android.text.TextUtils
import com.blankj.utilcode.util.EncodeUtils
import com.blankj.utilcode.util.SPUtils
import com.wswy.wzcx.AppContext
import com.wswy.wzcx.module.GlobalConfigManager
import com.wswy.wzcx.module.WReceiver
import com.wswy.wzcx.module.WService
import com.wswy.wzcx.statistics.BizReport
import com.wswy.wzcx.statistics.StatTools
import com.wswy.wzcx.statistics.StatisticsId
import okhttp3.*
import org.json.JSONObject
import timber.log.Timber
import java.io.IOException
import java.net.CookieManager
import java.net.HttpCookie
import java.net.URI
import java.util.concurrent.TimeUnit
import kotlin.random.Random

object Gov122 {

    private val NUM = "AB0CDEFG5HH1JKL3MN8PQ6RST9UW47X2YZ"

    data class GovResult(val code: Int? = 0,
                         val data: String? = null,
                         val commonParams: Map<String, String?>? = null
    )

    private class ProvData(val name: String, val addr: String, val code: String? = null)

    //随机ua
    private val UA = arrayOf("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:66.0) Gecko/20100101 Firefox/66.0",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36",
            "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
            "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36")


    private val carNo2PS = arrayOf(
            ProvData("京", "bj", "11"),  //北京
            ProvData("渝", "cq", "50"),  //重庆
            ProvData("沪", "sh", "31"),  //上海
            ProvData("津", "tj", "12"),  //天津

            ProvData("皖", "ah", "34"),  //安徽
            ProvData("闽", "fj", "35"),  //福建
            ProvData("粤", "gd", "44"), //广东
            ProvData("桂", "gx", "45"),  //广西

            ProvData("贵", "gz", "52"),  //贵州
            ProvData("甘", "gs", "62"),  //甘肃

            ProvData("冀", "he", "13"),  //河北
            ProvData("吉", "jl", "22"),  //吉林
            ProvData("黑", "hl", "23"),  //黑龙江

            ProvData("赣", "jx", "36"),  //江西
            ProvData("豫", "ha", "41"),  //河南
            ProvData("鄂", "hb", "42"),  //湖北
            ProvData("湘", "hn", "43"),  //湖南
            ProvData("琼", "hi", "46"),  //海南

            ProvData("晋", "sx", "14"),  //山西
            ProvData("蒙", "nm", "15"),  //内蒙古
            ProvData("辽", "ln", "21"),  //辽宁

            ProvData("鲁", "sd", "37"),  //山东
            ProvData("川", "sc", "51"),  //四川
            ProvData("陕", "sn", "61"),  //陕西
            ProvData("青", "qh", "63"),  //青海
            ProvData("宁", "nx", "64"),  //宁夏

            ProvData("云", "yn", "53"),  //云南
            ProvData("藏", "xz", "54"),  //西藏
            ProvData("新", "xj", "65"),  //新疆

            ProvData("浙", "zj", "33"),  //浙江
            ProvData("苏", "js", "32")   //江苏
    )

    private val JS122 = arrayOf(
            ProvData("A", "nkg", "3201"), //"320100","南京",
            ProvData("B", "wux", "3202"), //"320200","无锡",
            ProvData("C", "xuz", "3203"), //"320300","徐州",
            ProvData("D", "czx", "3204"), //"320400","常州",

            ProvData("E", "szv", "3205"), //"320500","苏州",
            ProvData("U", "szv", "3205"), //"320500","苏州",

            ProvData("F", "ntg", "3206"), //"320600","南通",
            ProvData("G", "lyg", "3207"), //"320700","连云港",
            ProvData("H", "has", "3208"), //"320800","淮安",
            ProvData("J", "ynz", "3209"), //"320900","盐城",

            ProvData("K", "yzo", "3210"), //"320100","扬州",
            ProvData("L", "zhe", "3211"), //"321100","镇江",
            ProvData("M", "tzs", "3212"), //"321200","泰州",
            ProvData("N", "suq", "3213") //"321300","宿迁",
    )


    private val ZJ122 = arrayOf(
            ProvData("A", "hgh", "3301"), //"330100","杭州",
            ProvData("B", "ngb", "3302"), //"330200","宁波",
            ProvData("C", "wnz", "3303"), //"330300","温州"
            ProvData("F", "jix", "3304"), //"330400","嘉兴"
            ProvData("E", "hzh", "3305"), //"330500","湖州"
            ProvData("D", "sxg", "3306"), //"330600","绍兴"
            ProvData("G", "jha", "3307"), //"330700","金华"
            ProvData("H", "quz", "3308"), //"330800","衢州"
            ProvData("L", "zos", "3309"), //"330900","舟山"
            ProvData("J", "tzz", "3310"), //"331000","台州"
            ProvData("K", "lss", "3311") //"331100","丽水"
    )

    private val cacheStrategy = CacheStrategy()

    //检查查询间隔
    private fun canQuery122(key: String): Boolean {
        //60s
        val lastTime = SPUtils.getInstance().getLong("122_${key}", 0)

        val canLast = lastTime == 0L || (System.currentTimeMillis() - lastTime) > GlobalConfigManager.getInstance().sysConf.gw122Interval() * 1000

        if (canLast) {

            val lastBan = SPUtils.getInstance().getLong("122_ban_${key}", 0)
            val canBan = lastBan == 0L || (System.currentTimeMillis() - lastBan) > 60 * 1000 * 30

            return canBan
        }

        return canLast
    }

    //被waf拦截，延迟一些
    private fun banProvWaf(key: String) {
        SPUtils.getInstance().put("122_ban_${key}", System.currentTimeMillis())
    }

    private fun saveLast(key: String) {
        SPUtils.getInstance().put("122_${key}", System.currentTimeMillis())
    }

    private fun logE(msg: String?) {
        Timber.e(msg)

        //BuglyLog.e("gw122",msg)

    }


    private fun query122(qv: GovInquiry): GovResult? {

        var inquiry: GovInquiry = qv

        //访问122关闭
        if (!GlobalConfigManager.getInstance().sysConf.isEnable122()) {
            return null
        }

        //缓存查找
        cacheStrategy.findCache(inquiry.getCacheKey())?.let {
            if (it.code == 500) {
                return GovResult(it.code, null, null)
            }
        }

        if (!inquiry.checkInput()) {

            StatTools.sendGovEvent("${inquiry.getQueryProv()}_${inquiry.getUrl()}_checkInput", false)

            return null
        } else {
            StatTools.sendGovEvent("${inquiry.getQueryProv()}_${inquiry.getUrl()}_checkInput", true)
        }

        val p = inquiry.getQueryProv()

        if (p.isNullOrEmpty()) {
            logE("无法对应省份 --- ${inquiry}")
            return null
        }

        val stTime = SystemClock.elapsedRealtime()

        val govKey = "${inquiry.getQueryProv()}_${inquiry.getUrl()}"

        if (!canQuery122(p)) {
            logE("查询太频繁---$govKey")
            return null
        }




        logE("122官网查询  $inquiry")

        val cookieManager = CookieManager()
        val login = "https://$p.122.gov.cn/views/inquiry.html"

        var retCode: Int = 0
        var retData: String? = null


        val loginUri = URI.create(login)

        val headers = Headers.of(mapOf("Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
                //"Accept-Encoding" to "gzip, deflate, br",
                "Accept-Language" to "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
                "Cache-Control" to "no-cache",
                "DNT" to "1",
                "User-Agent" to UA[Random.nextInt(UA.size)]))

        val client = Api.get().okHttpClient.newBuilder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .cookieJar(JavaNetCookieJar(cookieManager))
                .build()

        //1.请求首页,会保存cookie

        var flags: String? = null
        runCatching {
            client.newCall(Request.Builder().url(login)
                    .headers(headers)
                    .get()
                    .build()).execute()
        }.run {
            if (exceptionOrNull() is IOException) {
                flags = "timeout"
            }
        }

        if (cookieManager.get(loginUri, hashMapOf()).isNullOrEmpty()) {

            logE("使用webview 模式")

            StatTools.sendShow(AppContext.getContext(), StatisticsId.gw_122_webview, inquiry.getQueryProv())

            //如果触发了反扒模式，使用webview
            // 自动停止
            WReceiver.reset()

            Intent(AppContext.getContext(), WService::class.java).runCatching {
                putExtra("url", login)
                putExtra("ua", headers.get("User-Agent"))
                AppContext.getContext().startService(this)
            }

            //等待获取cookie
            val cookie = WReceiver.getCookie()

            logE("webview cookie -->   $cookie")

            if (flags != null && cookie.isNullOrEmpty()) {
                //超时
                BizReport.sendException(BizReport.GW122_TIMEOUT, govKey)
            }

            if (cookie.isNullOrEmpty()) {
                if (flags == null) {
                    flags = "web_cookie_empty"
                }
            } else {

                //多条cookie情况
                val cks = cookie.split(";")
                if (!cks.isNullOrEmpty()) {
                    cks.forEach {
                        HttpCookie.parse("Set-Cookie: $it")?.forEach {
                            cookieManager.cookieStore.add(loginUri, it)
                            flags = "web_cookie_ok"
                        } ?: run {
                            flags = "web_cookie_parse_error"
                        }
                    }
                } else {
                    HttpCookie.parse("Set-Cookie: $cks")?.forEach {
                        cookieManager.cookieStore.add(loginUri, it)
                        flags = "web_cookie_ok"
                    } ?: run {
                        flags = "web_cookie_parse_error"
                    }
                }

            }

        } else {
            flags = "url_cookie_ok"
        }


        //2. 获取验证码
        val vCode = "https://$p.122.gov.cn/captcha?nocache=${System.currentTimeMillis()}"

        val ccc = cookieManager.get(URI.create(vCode), hashMapOf())


        saveLast(p)

        if (ccc.isNullOrEmpty()) {

            StatTools.sendGovEvent("${govKey}_getcookie", false)

            logE("无法获取cookie $flags")
            return null
        } else {

            StatTools.sendGovEvent("${govKey}_getcookie", true)

            logE("获取cookie 成功！ $flags   $ccc")
        }

        var queryRetryCount = 3
        val commonParams = hashMapOf<String, String?>()

        inquiry.fillParams(commonParams)

        val realCarType = (inquiry as? FineVioInquiry)?.carType

        do {

            flags = null
            //初始化
            retCode = 0
            retData = null

            var base64Img: String? = null
            var captchaRetryCount = 3


            //2. 获取验证码
            do {
                val captchaResult = runCatching {
                    client.newCall(Request.Builder().url(vCode)
                            .headers(headers)
                            .header("Accept", "mage/webp,*/*")
                            .header("Referer", login)
                            .get()
                            .build()).execute().run {
                        if (isSuccessful) {
                            if (header("Content-Type")?.startsWith("text/html") == true) {
                                Timber.e(body()?.string())
                                flags = "get_captcha_resp_waf"
                                return@run null
                            }
                            return@run body()?.bytes()
                        } else {
                            flags = "get_captcha_resp_error"
                            Timber.e(body()?.string())
                            null
                        }
                    }
                }

                if (captchaResult.exceptionOrNull() is IOException) {
                    if (flags == null) {
                        flags = "get_captcha_timeout"
                    }
                    if (!flags.isNullOrEmpty()) {
                        BizReport.sendException(BizReport.GW122_ERROR, flags)
                    }

                    captchaRetryCount--
                    continue
                }

                val bytes = captchaResult.getOrNull()

                //判断验证码返回
                if (bytes == null || bytes.isEmpty()) {
                    if (flags == null) {
                        flags = "get_captcha_empty"
                    }
                    logE("get captcha error: $flags !   ${bytes?.contentToString()}  retry: ${captchaRetryCount}")

                    if (!flags.isNullOrEmpty()) {
                        BizReport.sendException(BizReport.GW122_ERROR, flags)
                    }

                    //被防火墙拦截，不要重试了
                    if (flags == "get_captcha_resp_waf") {
                        banProvWaf(p)
                        break
                    }
                    captchaRetryCount--
                    continue
                }
                base64Img = EncodeUtils.base64Encode2String(bytes)
                if (base64Img.isNullOrEmpty()) {
                    if (flags == null) {
                        flags = "get_captcha_base64_empty"
                    }

                    if (!flags.isNullOrEmpty()) {
                        BizReport.sendException(BizReport.GW122_ERROR, flags)
                    }

                    logE("base64Img error! retry: ${captchaRetryCount}")
                    captchaRetryCount--
                    continue
                }
                flags = "get_captcha_ok"
                break
            } while (captchaRetryCount > 0)

            if (base64Img.isNullOrEmpty()) {
                logE("get captcha error $flags")

                StatTools.sendGovEvent("${govKey}_getcaptcha", false)

                return null
            } else {

                StatTools.sendGovEvent("${govKey}_getcaptcha", true)

                logE("get captcha success ${captchaRetryCount}")
            }

            flags = null
            //3. 识别验证码
            var captchaCode: String? = null;
            var decodeRetryCount = 3
            do {

                //是否使用驾考识别接口

                var codeResult: Result<String?>? = null
                if (GlobalConfigManager.getInstance().sysConf.useJKDecode()) {

                    val request = Request.Builder().url(HttpUrl.get("https://jiaoguan.jiakaobaodian.com/api/internal/user/decode-image-code.htm")
                            .newBuilder()
                            .addQueryParameter("carNo", inquiry.getDecodeNo())
                            .addQueryParameter("count", "1")
                            .addQueryParameter("type", "122")
                            .addQueryParameter("status", "0")
                            .build()
                    )
                            .addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) )")
                            .addHeader("Connection", "close")
                            .addHeader("Accept", "*/*")
                            .addHeader("DNT", "1")
                            .addHeader("Referer", "https://$p.122.gov.cn/views/inquiry.html")
                            .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), base64Img))
                            .build()

                    codeResult = runCatching {
                        client.newCall(request).execute().let {

                            if (it.isSuccessful) {
                                it.body()?.string()
                            } else {
                                flags = "decode_captcha_resp_error"
                                null
                            }
                        }
                    }
                }

                if (codeResult == null) {
                    codeResult = runCatching {
                        Api.get().decodeCaptchaImage(base64Img, "122").blockingGet()?.orNull()
                    }
                }

                if (codeResult.exceptionOrNull() is IOException) {
                    if (flags == null) {
                        flags = "decode_captcha_timeout"
                    }
                    if (!flags.isNullOrEmpty()) {
                        BizReport.sendException(BizReport.GW122_ERROR, flags)
                    }
                    decodeRetryCount--
                    continue
                }

                if (codeResult.isFailure) {
                    decodeRetryCount--
                    continue
                }

                if (codeResult.getOrNull().isNullOrEmpty()) {
                    if (flags == null) {
                        flags = "decode_captcha_empty"
                    }

                    if (!flags.isNullOrEmpty()) {
                        BizReport.sendException(BizReport.GW122_ERROR, flags)
                    }

                    decodeRetryCount--
                    continue
                }
                captchaCode = codeResult.getOrNull()
                flags = "decode_captcha_ok"
                break
            } while (decodeRetryCount > 0)

            if (captchaCode.isNullOrEmpty()) {
                logE(flags)
                //重新获取验证码
                queryRetryCount--


                StatTools.sendGovEvent("${govKey}_decode_captcha", false)

                continue
            } else {

                StatTools.sendGovEvent("${govKey}_decode_captcha", true)


                logE(captchaCode)
            }

            flags = null

            val queryUrl = "https://$p.122.gov.cn/m/publicquery/${inquiry.getUrl()}"

            //3. 查询
            val jsonResult = runCatching {
                client.newCall(Request.Builder().url(queryUrl)
                        .headers(headers)
                        .header("Accept", "application/json, text/javascript, */*; q=0.01")
                        .header("Referer", login)
                        .header("X-Requested-With", "XMLHttpRequest")
                        .post(FormBody.Builder().apply {

                            inquiry.getQueryParams().forEach { (t, u) ->
                                u?.let {

                                    logE("query params $t --> $u")

                                    add(t, u)
                                }
                            }
                            add("captcha", captchaCode)
                        }
                                .build())
                        .build()).execute().let {

                    if (it.isSuccessful) {
                        it.body()?.string()
                    } else {

                        flags = "query_${govKey}_resp_error"

                        null
                    }


                }
            }

            if (jsonResult.exceptionOrNull() is IOException) {
                //网络错误
                if (flags == null) {
                    flags = "query_${govKey}_time_out"
                }
            }

            logE("resp -- ${jsonResult.getOrNull()}")

            val json = jsonResult.getOrNull()

            if (!flags.isNullOrEmpty()) {
                BizReport.sendException(BizReport.GW122_ERROR, flags)
            }

            if (!json.isNullOrEmpty()) {
                //
                try {
                    val jsonObject = JSONObject(json)

                    val jCode = jsonObject.optInt("code", -1)
                    val jData = jsonObject.optJSONObject("data")

                    retCode = jCode
                    retData = jData?.toString()

                    flags = "query_${govKey}_${retCode}"


                    StatTools.sendGovEvent("${govKey}_data_${jCode}", true)


                    when (jCode) {
                        0, 499 -> {
                            //0 接口错误
                            //499 验证码错误
                            //重试
                            queryRetryCount--

                        }
                        200, 500 -> {
                            //200 正确
                            //500 输入参数错误，车牌发动机号等不对
                            if (jCode == 500 && inquiry is FineVioInquiry) {
                                //更换车辆类型

                                val tmpInquiry = inquiry.changeType()
                                //如果没有改变过类型
                                if (realCarType != null && !TextUtils.equals(realCarType, tmpInquiry.carType)) {
                                    //没有改过类型，改变后再次查询

                                    inquiry = tmpInquiry

                                    //再次查询
                                    commonParams.clear()
                                    inquiry.fillParams(commonParams)

                                    queryRetryCount--


                                } else {
                                    queryRetryCount = 0
                                    //保存数据
                                    commonParams["imgBase64"] = base64Img
                                    commonParams["imgCode"] = captchaCode
                                }
                            } else {
                                queryRetryCount = 0

                                //上报验证码
                                reportCaptcha(inquiry, base64Img, captchaCode)

                                //保存数据
                                commonParams["imgBase64"] = base64Img
                                commonParams["imgCode"] = captchaCode

                            }

                        }

                        else -> {
                            //其它错误，重试
                            queryRetryCount--
                        }
                    }
                } catch (e: Throwable) {
                    logE(e.message)
                    queryRetryCount--
                    flags = "query_${inquiry.getUrl()}_jsonerror"

                    StatTools.sendGovEvent("${govKey}_data", false)

                    BizReport.sendException(BizReport.GW122_PARSE_ERROR, "${govKey}_${json}")
                }

            } else {
                if (flags == null) {
                    flags = "query_${inquiry.getUrl()}_empty"
                }
                //获取到的数据错误 ，尝试重试
                queryRetryCount--
                StatTools.sendGovEvent("${govKey}_data", false)
            }

        } while (queryRetryCount > 0)

        logE("122 time: ${SystemClock.elapsedRealtime() - stTime}")

        commonParams["code"] = retCode.toString()
        commonParams["data"] = retData

        commonParams["url"] = inquiry.getUrl()


        if (retCode == 200 || retCode == 500) {
            cacheStrategy.putCache(inquiry.getCacheKey(), retCode, null)
        }

        StatTools.sendGovTime(govKey, SystemClock.elapsedRealtime() - stTime)

        return GovResult(retCode, retData, commonParams)
    }

    @JvmStatic
    @WorkerThread
    fun get122CarData(carNo: String?, engineNo: String?, carType: String? = "02"): GovResult? {
        val len = engineNo?.length ?: 0
        var eno = engineNo
        if (len > 6) {
            //长度超过6位 截取
            eno = engineNo?.substring(len - 6, len)
        }
        val inquiry = FineVioInquiry(carNo, eno, carType)
        return query122(inquiry)
    }

    @JvmStatic
    @WorkerThread
    fun get122ScoreData(jszh: String?, dabh: String?): GovResult? {
        val inquiry = Gov122.ScoreInquiry(jszh, dabh)
        return query122(inquiry)
    }


    private interface GovInquiry {

        fun getUrl(): String

        fun getQueryParams(): Map<String, String?>

        fun checkInput(): Boolean

        fun getQueryProv(): String?

        fun getDecodeNo(): String

        fun fillParams(map: MutableMap<String, String?>)

        fun getCacheKey(): String
    }


    /**
     * 机动车违法查询
     */
    private class FineVioInquiry(private val carNo: String?,
                                 private val engineNo: String?,
                                 val carType: String? = "02") : GovInquiry {

        fun changeType(): FineVioInquiry {
            //转换类型
            val type = when (carType) {
                //"01" -> "02"
                //"02" -> "01"
                "51" -> "52"
                "52" -> "51"
                else -> carType
            }

            return FineVioInquiry(carNo, engineNo, type)
        }

        override fun getCacheKey(): String {
            return "${carNo}_${engineNo}"
        }

        override fun fillParams(map: MutableMap<String, String?>) {

            map["type"] = getUrl()
            map["carNo"] = carNo
            map["carType"] = carType

        }

        override fun checkInput(): Boolean {

            if (carNo.isNullOrEmpty() || carNo.length < 5) {
                logE("车牌号错误：$carNo")
                return false
            }
            if (engineNo.isNullOrEmpty() || engineNo.length < 6) {
                logE("发动机号错误：$engineNo")
                return false
            }

            return true
        }

        override fun getQueryProv(): String? {
            carNo ?: return null
            if (carNo.length < 4) {
                return null
            }
            val c = carNo2PS.find { it.name == carNo.substring(0, 1) }?.addr
            //对浙江和江苏特殊处理
            return when (c) {
                "zj" -> ZJ122.find { it.name == carNo.substring(1, 2) }?.addr
                "js" -> JS122.find { it.name == carNo.substring(1, 2) }?.addr
                else -> c
            }
        }

        override fun getUrl(): String = "vio"

        override fun getDecodeNo(): String {
            return carNo ?: ""
        }

        override fun getQueryParams(): Map<String, String?> {
            return HashMap<String, String?>().apply {
                put("hpzl", carType)
                put("hphm", carNo)
                put("hphm1b", carNo?.substring(1))
                put("fdjh", engineNo)
                put("qm", "wf")
                put("page", "1")
            }
        }

        override fun toString(): String {
            return "${getQueryProv()}  $carNo  $engineNo  $carType"
        }

    }


    /**
     * 驾照查分
     */
    private class ScoreInquiry(private val jszh: String?,
                               private val dabh: String?) : GovInquiry {
        override fun getCacheKey(): String {
            return "${jszh}_${dabh}"
        }

        override fun fillParams(map: MutableMap<String, String?>) {

            map["type"] = getUrl()
            map["file_number"] = dabh
            map["number"] = jszh

        }

        override fun checkInput(): Boolean {

            if (jszh.isNullOrEmpty() || jszh.length < 15) {
                logE("驾驶证号错误：$jszh")
                return false
            }
            if (dabh.isNullOrEmpty() || dabh.length < 10) {
                logE("档案编号错误：$dabh")
                return false
            }

            return true
        }

        override fun getQueryProv(): String? {
            val p = dabh?.substring(0, 2)
            val paddr = carNo2PS.find { it.code == p }?.addr

            //浙江和江苏 特殊处理
            return when (paddr) {
                "js" -> JS122.find { it.code == dabh?.substring(0, 4) }?.addr
                "zj" -> ZJ122.find { it.code == dabh?.substring(0, 4) }?.addr
                else -> paddr
            }
        }

        override fun getDecodeNo(): String {
            return ""
        }

        override fun getUrl(): String = "scores"

        override fun getQueryParams(): Map<String, String?> {

            return HashMap<String, String?>().apply {
                put("jszh", jszh)
                put("dabh", dabh)
                put("qm", "wf")
                put("page", "1")
            }
        }

        override fun toString(): String {
            return "${getQueryProv()} $jszh  $dabh"
        }
    }

    private fun randomCarNo(): String {

        //随机生成一个车牌号
        val sb = StringBuilder()
        sb.append(carNo2PS.random().name)
        sb.append("ABCDEFGHJKLMN".random())
        for (i in 0 until 5) {
            sb.append(NUM.random())
        }
        return sb.toString()
    }


    private fun reportCaptcha(inquiry: GovInquiry, base64Image: String, code: String) {

        Timber.e("reportCaptcha ${inquiry.getQueryProv()} ${inquiry.getUrl()} $code  ${base64Image.length}")

    }


    private class CacheBean(val code: Int = 0, val value: String?)
    private class CacheStrategy {
        private val localCache = LruCache<String, CacheBean>(32)

        fun findCache(key: String): CacheBean? {
            return localCache.get(key)
        }

        fun putCache(key: String, code: Int = 0, value: String?) {

            localCache.put(key, CacheBean(code, value))
        }

    }


    fun findProvNameByCode(code: String): String? {
        return carNo2PS.find { it.code == code }?.name
    }
}